/* RESPOKANEPixelRectangle class
	by: randy bacon
	10/03/06
	Used to contain a rectangle based on a pixels - using google GPoint() for x,y
*/
function RESPOKANEPixelRectangle()
{
	//class members (consider _ members private)
	this._LeftTop;
	this._RightBottom;
	
	//inline constructor
	this.Init(arguments);
}

//RESPOKANEPixelRectangle :: Init :: constructor of the sorts
RESPOKANEPixelRectangle.prototype.Init = function(args)
{
	if( args.length == 2)
	{
		//assume we have 2 google points
		this._LeftTop = args[0];
		this._RightBottom = args[1];
	}
	else( args.length == 4)
	{
		this._LeftTop = new GPoint(args[0], args[1]);
		this._RightBottom = new GPoint(args[2], args[3]);
	}
}

//RESPOKANEPixelRectangle :: GetRightBottom :: get for the right bottom member
RESPOKANEPixelRectangle.prototype.GetRightBottom = function()
{
	return this._RightBottom;
}

//RESPOKANEPixelRectangle :: GetLeftTop :: get for the left top member
RESPOKANEPixelRectangle.prototype.GetLeftTop = function()
{
	return this._LeftTop;
}

//RESPOKANEPixelRectangle :: toString :: override object toString
RESPOKANEPixelRectangle.prototype.toString =  function()
{
	return "LeftTopX: " + this._LeftTop.x + " LeftTopY: " + this._LeftTop.y + " RightBottomX: " + this._RightBottom.x + " RightBottomY: " + this._RightBottom.y;
}

//RESPOKANEPixelRectangle :: InBox :: see if a X,Y point is inside this box
//caller is responsible for having box set up correctly
RESPOKANEPixelRectangle.prototype.InBox = function(pointX, pointY)
{
	if ( pointX > this._LeftTop.x && pointX < this._RightBottom.x && pointY < this._RightBottom.y && pointY > this._LeftTop.y )
		return true;
	else
		return false;
}

//RESPOKANEPixelRectangle :: DrawDivBox :: draws our box as a div positioned relative to an element
//mostly for debugging - element must be an element object
RESPOKANEPixelRectangle.prototype.DrawDivBox = function(elem)
{
	if( elem != null )
	{
		//create the div
		var div = document.createElement("div");
 			div.style.border = "1px solid red";
		div.style.position = "absolute";
		div.style.width = (this._RightBottom.x - this._LeftTop.x) + "px";
		div.style.height = (this._RightBottom.y - this._LeftTop.y) + "px";
		div.style.left = this._LeftTop.x + "px";
		div.style.top = this._LeftTop.y + "px";
		//attach it to our elem
		elem.appendChild(div);
	}
}
//end --------- RESPOKANEPixelRectangle

/*  RESPOKANEGoogleMap class
	by: randy bacon
	10/03/06
	Control and instance of a google map and the search interface
*/

//RESPOKANEGoogleMap CONSTANTS
var RESPOKANEMAPOBJ;
var GOOGMAP_ELEM = "respokaneGoogleMap";
var GOOGMAPOVERLAY_ELEM = "respokaneGoogleMapOverlay";
var RESPOKANEZOOMTOOL_ELEM = "respokaneMapToolBox";
var RESPOKANEDEFAULTTOOL_ELEM = "respokaneMapToolDrag";
var RESPOKANEREMOVEBOX_ELEM = "respokaneRemoveMapBox";
var RESPOKANEREMOVENOBOX_ELEM = "respokaneRemoveMapBoxDisabled";
var ZOOMAREA_KEYCODE = 90; //z
var MOUSELOCATION_X = 0;
var MOUSELOCATION_Y = 0;
var IMAGEBASE_URL = "http://images.graphicaldata.com/zoommaps/";
var GOOGLEMAPO;
var RESPOKANEWAITBNDRAWS = 800;
var RESPOKANETOOLDEFAULT = 0;
var RESPOKANETOOLZOOMBOX = 1;
var RESPOKANECURRTOOL = RESPOKANETOOLDEFAULT;
var RESPOKANEBGON = 1;
var RESPOKANEBGOFF = 2;
var RESPOKANEBGNA = 3;
var RESPOKANETOOLCLASSES = new Array();
RESPOKANETOOLCLASSES[RESPOKANETOOLDEFAULT] = new Array();
RESPOKANETOOLCLASSES[RESPOKANETOOLDEFAULT][0] = RESPOKANEDEFAULTTOOL_ELEM;
RESPOKANETOOLCLASSES[RESPOKANETOOLDEFAULT][RESPOKANEBGON] = null;
RESPOKANETOOLCLASSES[RESPOKANETOOLDEFAULT][RESPOKANEBGOFF] = null;
RESPOKANETOOLCLASSES[RESPOKANETOOLZOOMBOX] = new Array();
RESPOKANETOOLCLASSES[RESPOKANETOOLZOOMBOX][0] = RESPOKANEZOOMTOOL_ELEM;
RESPOKANETOOLCLASSES[RESPOKANETOOLZOOMBOX][RESPOKANEBGON] = null;
RESPOKANETOOLCLASSES[RESPOKANETOOLZOOMBOX][RESPOKANEBGOFF] = null;

function RESPOKANEGoogleMap()
{
	//class members (consider _ members private)
	this._respokaneMap;	
	this._respokaneMGoogleZoomSC;
	this._respokaneMGoogleOverMC;
	this._PolyOutline = null;		
	this._respokaneMapInitCenter;
	this._respokaneMapInitZoom;
	this._SearchResultsView = false;
	this._respokaneRemoveBoxLink;
	this._respokaneNoRemoveBoxLink;
			
	//class props
	this.RESPOKANEMPixelOffset;
	this.RESPOKANEMBounds;
	this.MapParams = new RESPOKANEMapParams();
	this.RESPOKANEZoomBox = new RESPOKANEZoomBox();
	this.PlyPoints;
	this.BoxLineColor = "#CC0202";
	this.BoxLineWidth = 2;
	this.BoxLineTrans = .65;
	this.RESPOKANEMapOverlay;	
}
	
//RESPOKANEGoogleMap :: Init :: create our map instance and build
//call with (center lat, center long, zoom, polyPoints) OR (NE lat, NE long, SW lat, SW long, polyPoints)
RESPOKANEGoogleMap.prototype.Init = function()
{
	if( arguments.length == 4 || arguments.length == 5 )
	{
		//map elem
		this._respokaneMap = document.getElementById(GOOGMAP_ELEM);
		//shared map set up
		this.RESPOKANEMapOverlay = document.getElementById(GOOGMAPOVERLAY_ELEM);
		//create map
		GOOGLEMAPO = new GMap2(this._respokaneMap);
		//add controls
		GOOGLEMAPO.addControl(new GLargeMapControl());
		GOOGLEMAPO.addControl(new GScaleControl());
		//var OMap = new GOverviewMapControl();
     	//	GOOGLEMAPO.addControl(OMap);
		//OMap.hide(); 
		//allow google zooms
		this.EnableG();
	}
	if( arguments.length == 4)
	{
		//now set the center and zoom in
		GOOGLEMAPO.setCenter(new GLatLng(arguments[0], arguments[1]), arguments[2]); 
		this.PlyPoints = arguments[3];
		this._respokaneMapInitCenter = new GLatLng(arguments[0], arguments[1]);
		this._respokaneMapInitZoom = arguments[2];
	}
	else if( arguments.length == 5)
	{
		//get the bounds and zoom in
		var neCrn = new GLatLng(arguments[0], arguments[1]);
		var swCrn = new GLatLng(arguments[2], arguments[3]);
		var rsBounds = new GLatLngBounds(swCrn, neCrn);
		
		//build map and center
		GOOGLEMAPO.setCenter(rsBounds.getCenter(), GOOGLEMAPO.getBoundsZoomLevel(rsBounds));
		this.PlyPoints = arguments[4];
		this._respokaneMapInitCenter = rsBounds.getCenter();
		this._respokaneMapInitZoom = GOOGLEMAPO.getBoundsZoomLevel(rsBounds);
	}
	
	if( arguments.length == 4 || arguments.length == 5 )
	{
		//initalize tools and zoom
		this._ZoomInit();
	}
	
	//draw box if we are told to
	if( arguments.length == 5 )
	{
		this.PlyPoints = arguments[4];
		this.DrawPolyBox(true, true);
		//fire poly bounds changed
		this.LPolyBoundsChanged();
	}
}
	
//RESPOKANEGoogleMap :: _ZoomInit :: method to init our zoom tools and objs
RESPOKANEGoogleMap.prototype._ZoomInit = function()
{
	//set up some element refs
	this.RESPOKANEMPixelOffset = respokaneGloGetObjectOffset(this._respokaneMap);
	
	RESPOKANETOOLCLASSES[RESPOKANETOOLDEFAULT][RESPOKANEBGON] = document.getElementById(RESPOKANEDEFAULTTOOL_ELEM + "BGOn");
	RESPOKANETOOLCLASSES[RESPOKANETOOLDEFAULT][RESPOKANEBGOFF] = document.getElementById(RESPOKANEDEFAULTTOOL_ELEM + "BGOff");
	RESPOKANETOOLCLASSES[RESPOKANETOOLZOOMBOX][RESPOKANEBGON] = document.getElementById(RESPOKANEZOOMTOOL_ELEM + "BGOn");
	RESPOKANETOOLCLASSES[RESPOKANETOOLZOOMBOX][RESPOKANEBGOFF] = document.getElementById(RESPOKANEZOOMTOOL_ELEM + "BGOff");
	
	this._respokaneRemoveBoxLink = document.getElementById(RESPOKANEREMOVEBOX_ELEM);
	this._respokaneNoRemoveBoxLink = document.getElementById(RESPOKANEREMOVENOBOX_ELEM);
	
	//bind event for mouse and key down/up
	document.onmousemove = this.MouseMoveH;
	document.onkeyup = this.KeyUpH;
	document.onkeydown = this.KeyDownH;
	
	//set up our map pixel bounds
	this.RESPOKANEMBounds = new RESPOKANEPixelRectangle(this.RESPOKANEMPixelOffset.x, this.RESPOKANEMPixelOffset.y, this.RESPOKANEMPixelOffset.x + parseFloat(this._respokaneMap.style.width), this.RESPOKANEMPixelOffset.y + parseFloat(this._respokaneMap.style.height));

	//slider
	this._respokaneMGoogleZoomSC = new RESPOKANEPixelRectangle(this.RESPOKANEMBounds.GetLeftTop().x + 7, this.RESPOKANEMBounds.GetLeftTop().y + 7, this.RESPOKANEMBounds.GetLeftTop().x + 62, this.RESPOKANEMBounds.GetLeftTop().y + 260);
	//overview expander
	this._respokaneMGoogleOverMC = new RESPOKANEPixelRectangle(this.RESPOKANEMBounds.GetRightBottom().x - 15, this.RESPOKANEMBounds.GetRightBottom().y - 15, this.RESPOKANEMBounds.GetRightBottom().x, this.RESPOKANEMBounds.GetRightBottom().y);

	//tell zoom tool to go
	this.ChangeToolState(RESPOKANETOOLDEFAULT);
	
	//add listener for our mouse down to the overlay
	GEvent.addDomListener(this.RESPOKANEMapOverlay, 'mousedown', this.MouseDownH); 
	GEvent.addDomListener(this.RESPOKANEMapOverlay, 'mouseup', this.MouseUpH); 
	
	//add handler for zoom
	GEvent.addListener(GOOGLEMAPO, "zoomend", function()
	{
		glZoomChanged();
	});
	
	//add move end handler
	GEvent.addListener(GOOGLEMAPO, "moveend", glCenterChanged);
		
	//fire params listners
	this.LFireAllListners();
		
	//put focus on my frame
	document.body.focus();
}

//RESPOKANEGoogleMap :: ChangeToolState :: changes the map tool state and selection
RESPOKANEGoogleMap.prototype.ChangeToolState = function(selTool)
{
	if( selTool != RESPOKANECURRTOOL)
	{
		RESPOKANECURRTOOL = selTool;
		var tmpState = "";
		for(var i=0;i<RESPOKANETOOLCLASSES.length;i++)
		{
			if( i == RESPOKANECURRTOOL)
			{
				RESPOKANETOOLCLASSES[i][RESPOKANEBGON].style.display = "block";
				RESPOKANETOOLCLASSES[i][RESPOKANEBGOFF].style.display = "none";
			}
			else
			{
				RESPOKANETOOLCLASSES[i][RESPOKANEBGON].style.display = "none";
				RESPOKANETOOLCLASSES[i][RESPOKANEBGOFF].style.display = "block";							
			}
		}
	}
}

//RESPOKANEGoogleMap :: SetMapType :: change the map type
RESPOKANEGoogleMap.prototype.SetMapType = function(selectedType)
{
	//V2 map types: G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP
	switch(selectedType)
	{
		case "2":
			GOOGLEMAPO.setMapType(G_HYBRID_MAP);
			break;
		case "1":
			GOOGLEMAPO.setMapType(G_SATELLITE_MAP);
			break;
		default:
			GOOGLEMAPO.setMapType(G_NORMAL_MAP);
			break;
	}
}

//RESPOKANEGoogleMap :: CurrentSearchBounds :: returns the current poly or the map bounds
RESPOKANEGoogleMap.prototype.CurrentSearchBounds = function()
{
	if( this.MapParams.MLPolyBounds.value == "" )
		return this.MapParams.Corners();
	else
		return this.MapParams.MLPolyBounds.value;
}

//RESPOKANEGoogleMap :: Dispose :: clean up our events
RESPOKANEGoogleMap.prototype.Dispose = function()
{
	document.onmousemove = null;
	document.onkeyup = null;
	document.onkeydown = null;
}

//RESPOKANEGoogleMap :: ResetSearch :: reset map to our initial settings
RESPOKANEGoogleMap.prototype.ResetSearch = function()
{
	//clear map overlays
	GOOGLEMAPO.clearOverlays();
	//then recenter and zoom map
	this.CenterMap(this._respokaneMapInitCenter, this._respokaneMapInitZoom);
	this.ResetAllToolsNoReCenter();
}

//RESPOKANEGoogleMap :: ResetAllToolsNoReCenter :: resets all the tools and borders and poly points without recenter or zoom
RESPOKANEGoogleMap.prototype.ResetAllToolsNoReCenter = function()
{
	//change to default tool
	this.ChangeToolState(RESPOKANETOOLDEFAULT);
	//reset tools
	this.ResetTools(false, true);
	//clear poly points
	this.PlyPoints = null;
	//reset box complete
	this.RESPOKANEZoomBox.ResetComplete(false);
	//clear draw box
	this.RemoveBorderBox();
	//then tell listner we have poly bounds changed
	this.LPolyBoundsChanged();
	//hide remove box option
	this._respokaneNoRemoveBoxLink.style.display = "block";
	this._respokaneRemoveBoxLink.style.display = "none";
}

//RESPOKANEGoogleMap :: PolyArray :: turns a correctly formatted string into an array of poly points
RESPOKANEGoogleMap.prototype.PolyArray = function(plyStr)
{
	var plyArray = new Array()
	var indItems = plyStr.split(',');
	if( indItems.length > 0)
	{
		for(var i = 0; i<indItems.length; i++)
		{
			var innerItem = indItems[i].split('~');
			if( innerItem.length == 2)
			{
				plyArray.push(new GLatLng(innerItem[0], innerItem[1]));
			}
		}
	}
	else
	{
		return null;
	}
	return plyArray;
}

//RESPOKANEGoogleMap :: DrawPolyBox :: method to draw our poly box on the map
RESPOKANEGoogleMap.prototype.DrawPolyBox = function(isABox, closeItUp)
{
	this.RemoveBorderBox();
	if( this.PlyPoints != null )
	{
		var points;
		if( this.PlyPoints.length == 2 && isABox)
		{
			points = this.BoxCorners(this.PlyPoints);
		}
		else
		{
			points = this.PlyPoints;
			if( closeItUp )
				points.push(points[0]);
		}
		//now we draw the box
		this._PolyOutline = new GPolyline(points, this.BoxLineColor, this.BoxLineWidth, this.BoxLineTrans);
		GOOGLEMAPO.addOverlay(this._PolyOutline);
		//and we show the remove box link
		this._respokaneRemoveBoxLink.style.display = "block";
		this._respokaneNoRemoveBoxLink.style.display = "none";
	}
}

//RESPOKANEGoogleMap :: BoxCorners :: expects a 2 point array will return an array of box points
RESPOKANEGoogleMap.prototype.BoxCorners = function(points)
{
	var boxPoints = new Array();
	//pass box on corners above
	boxPoints[0] = new GLatLng(points[0].y, points[1].x);
	boxPoints[1] = points[0];
	boxPoints[2] = new GLatLng(points[1].y, points[0].x);
	boxPoints[3] = points[1];
	boxPoints[4] = new GLatLng(points[0].y, points[1].x);
	return boxPoints;
}

//RESPOKANEGoogleMap :: RemoveBorderBox :: removes the border box from the map if there is one
RESPOKANEGoogleMap.prototype.RemoveBorderBox = function()
{
	if( this._PolyOutline != null && this._PolyOutline != 'undefined')
		GOOGLEMAPO.removeOverlay(this._PolyOutline);
}

//RESPOKANEGoogleMap :: PixelToLatLng :: return a lat/long from a gpoint pixel location
RESPOKANEGoogleMap.prototype.PixelToLatLng = function(gPointVr)
{
	return GOOGLEMAPO.fromContainerPixelToLatLng(gPointVr)
}

//RESPOKANEGoogleMap :: LatLngToPixel :: return a pixel from a gLatLong point
RESPOKANEGoogleMap.prototype.LatLngToPixel = function(gLatLong)
{
	return GOOGLEMAPO.fromLatLngToDivPixel(gLatLong)
}

//RESPOKANEGoogleMap :: FindPointXY :: find the point x,y of an item on the map by lat/long
RESPOKANEGoogleMap.prototype.FindPointXY = function(gLatLongPoint)
{
	var pointOffset = this.LatLngToPixel(gLatLongPoint);
	var pointSW = GOOGLEMAPO.fromLatLngToDivPixel(GOOGLEMAPO.getBounds().getSouthWest());
	var pointNE = GOOGLEMAPO.fromLatLngToDivPixel(GOOGLEMAPO.getBounds().getNorthEast()); 
	var x =  pointOffset.x - pointSW.x;
	var y = pointOffset.y - pointNE.y; 
	return new GPoint(x, y);
}

//RESPOKANEGoogleMap :: DisableG :: disable google drag and zoom
RESPOKANEGoogleMap.prototype.DisableG = function()
{
	GOOGLEMAPO.disableDoubleClickZoom();
	GOOGLEMAPO.disableDragging();
}

//RESPOKANEGoogleMap :: EnableG :: enable google drag and zoom
RESPOKANEGoogleMap.prototype.EnableG = function()
{
	GOOGLEMAPO.enableDoubleClickZoom();
	GOOGLEMAPO.enableDragging();
}

//RESPOKANEGoogleMap :: MouseDownH :: event handler for the mouse down event
RESPOKANEGoogleMap.prototype.MouseDownH = function(e)
{
	if (!e) 
		e = window.event;
	if(!RESPOKANEMAPOBJ.RESPOKANEZoomBox.MClickEnabled)
		return;
	RESPOKANEMAPOBJ.RESPOKANEZoomBox.StartDraw(false);
}

//RESPOKANEGoogleMap :: MouseUpH :: event handler for the mouse up event
RESPOKANEGoogleMap.prototype.MouseUpH =function(e)
{
	if (!e) 
		e = window.event;
	if(!RESPOKANEMAPOBJ.RESPOKANEZoomBox.MClickEnabled)
		return;
	RESPOKANEMAPOBJ.RESPOKANEZoomBox.EndDraw();
}

//RESPOKANEGoogleMap :: MouseMoveH :: event handler for the mouse move
RESPOKANEGoogleMap.prototype.MouseMoveH = function(e)
{
	//capture current mouse event
	if (!e) 
		e = window.event;
	
	//get mouse location
	if (e.pageX || e.pageY) 	
	{
		MOUSELOCATION_X = e.pageX;
		MOUSELOCATION_Y = e.pageY;
	}
	else if (e.clientX || e.clientY) 	
	{
		MOUSELOCATION_X = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
		MOUSELOCATION_Y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}
	
	//see if we need to show/hide our mask
	if( RESPOKANEMAPOBJ.RESPOKANEZoomBox.MClickEnabled && !RESPOKANEMAPOBJ.RESPOKANEZoomBox.IsInSearch() )
		if( RESPOKANEMAPOBJ.PointerOverMask() )
			RESPOKANEMAPOBJ.RESPOKANEMapOverlay.style.display = "none";
		else
			RESPOKANEMAPOBJ.RESPOKANEMapOverlay.style.display = "inline";
	
	//alert zoom to movement
	RESPOKANEMAPOBJ.RESPOKANEZoomBox.Move();
	//document.getElementById("debug").value="mousemove:" + MOUSELOCATION_X + "," + MOUSELOCATION_Y;
}

//RESPOKANEGoogleMap :: KeyUpH :: event handler for the key up
RESPOKANEGoogleMap.prototype.KeyUpH = function(e)
{
	if (!e) 
		e = window.event;
		
	if (e.keyCode != ZOOMAREA_KEYCODE)
		return;
	
	//tell zoom to end 
	RESPOKANEMAPOBJ.RESPOKANEZoomBox.EndDraw();
}

//RESPOKANEGoogleMap :: KeyDownH :: event handler for the key down
RESPOKANEGoogleMap.prototype.KeyDownH = function(e)
{
	if (!e) 
		e = window.event;
	if (e.keyCode == ZOOMAREA_KEYCODE)
	{
		//tell zoom tool start
		RESPOKANEMAPOBJ.RESPOKANEZoomBox.StartDraw(true);
	}
}

//RESPOKANEGoogleMap :: ResetTools :: method to reset all our tools
RESPOKANEGoogleMap.prototype.ResetTools = function()
{
	//set map items
	this._respokaneMap.style.cursor = "default";
	this.EnableG();
	//then reset tools
	this.RESPOKANEZoomBox.Reset();
	this.RESPOKANEZoomBox.ClickSearchState();
}

//RESPOKANEGoogleMap :: LFireAllListners :: fire all listners to update map params
RESPOKANEGoogleMap.prototype.LFireAllListners = function()
{
	this.LZoomChanged();
	this.LCenterChanged();
	this.LPolyBoundsChanged();
}

//RESPOKANEGoogleMap :: LZoomChanged :: listner for zoom level changed
RESPOKANEGoogleMap.prototype.LZoomChanged = function()
{
	this.MapParams.MLZoomLevel.value = GOOGLEMAPO.getZoom();
}

//RESPOKANEGoogleMap :: LCenterChanged :: listner for center of map changed
RESPOKANEGoogleMap.prototype.LCenterChanged = function()
{
	var mapLTLNBounds = GOOGLEMAPO.getBounds();
	this.MapParams.MLNECorner.value = mapLTLNBounds.getNorthEast().y + "~" + mapLTLNBounds.getNorthEast().x;
	this.MapParams.MLSWCorner.value = mapLTLNBounds.getSouthWest().y + "~" + mapLTLNBounds.getSouthWest().x;
	if( !this.RESPOKANEZoomBox.IsInCenterAndZoom())
	{
		this.ResetAllToolsNoReCenter();
	}
}

//RESPOKANEGoogleMap :: LPolyBoundsChanged :: poly bounds changed
RESPOKANEGoogleMap.prototype.LPolyBoundsChanged = function()
{
	this.MapParams.MLPolyBounds.value = "";
	if( this.PlyPoints != null )
	{
		for(var i = 0; i<this.PlyPoints.length; i++)
		{
			if( i>0 )
				this.MapParams.MLPolyBounds.value += ",";
			this.MapParams.MLPolyBounds.value += this.PlyPoints[i].y + "~" + this.PlyPoints[i].x;
		}
	}
}

//RESPOKANEGoogleMap :: UpdatePolyPointsL :: update the poly points listener WITHOUT searching
RESPOKANEGoogleMap.prototype.UpdatePolyPointsL = function()
{
	this.MapParams.MLPolyBounds.value = "";
	if( this.PlyPoints != null )
	{
		for(var i = 0; i<this.PlyPoints.length; i++)
		{
			if( i>0 )
				this.MapParams.MLPolyBounds.value += ",";
			this.MapParams.MLPolyBounds.value += this.PlyPoints[i].y + "~" + this.PlyPoints[i].x;
		}
		if( this.PlyPoints.length == 2 )
		{
			this.RESPOKANEZoomBox.ResetComplete(true);
		}
		else
		{
			this.RESPOKANEZoomBox.ResetComplete(false);
		}
	}
}

//RESPOKANEGoogleMap :: PointerInMapBounds :: sees if the mouse is currently within the map bounds
RESPOKANEGoogleMap.prototype.PointerInMapBounds = function()
{
	return this.RESPOKANEMBounds.InBox( MOUSELOCATION_X, MOUSELOCATION_Y );
}

//RESPOKANEGoogleMap :: PointerOverMask :: sees if the mouse is currently over the mask
RESPOKANEGoogleMap.prototype.PointerOverMask = function()
{
	//see if over the zoom slider box
	if( this._respokaneMGoogleZoomSC.InBox(MOUSELOCATION_X, MOUSELOCATION_Y) )
	{
		return true;
	}
	//see if over the map overview expand
	else if( this._respokaneMGoogleOverMC.InBox(MOUSELOCATION_X, MOUSELOCATION_Y) )
	{
		return true;
	}
	return false;	
}

//RESPOKANEGoogleMap :: CenterMap :: method to zoom and center map on current bounds
//wants (GLatLng, zoomLevel) or (GLatLngBounds)
RESPOKANEGoogleMap.prototype.CenterMap = function()
{
	if( arguments.length == 2 )
	{
		GOOGLEMAPO.setCenter(arguments[0], arguments[1]); 
	}
	else
	{
		GOOGLEMAPO.setCenter(arguments[0].getCenter(), GOOGLEMAPO.getBoundsZoomLevel(arguments[0])); 
	}
}

//global functions to give alerts for map
function glCenterChanged()
{
	//alert change
	RESPOKANEMAPOBJ.LCenterChanged();
	//check if we need to get points
	if( !RESPOKANEMAPOBJ.RESPOKANEZoomBox.IsBoxComplete())
		RESPOKANEMAPOBJ.LPolyBoundsChanged();
}

function glZoomChanged()
{
	//alert change
	RESPOKANEMAPOBJ.LZoomChanged();
	//check if we need to get points
	if( !RESPOKANEMAPOBJ.RESPOKANEZoomBox.IsBoxComplete())
		RESPOKANEMAPOBJ.LPolyBoundsChanged();
}
//end --------- RESPOKANEGoogleMap

//functions for client interaction with a set up google map object
function UnloadRESPOKANEMap()
{
	if(typeof(RESPOKANEMAPOBJ) != "undefined")
		RESPOKANEMAPOBJ.Dispose();
	RESPOKANEMAPOBJ = null;
}

function zToolChangeHandler(selTool)
{
	RESPOKANEMAPOBJ.ChangeToolState(selTool);
	RESPOKANEMAPOBJ.ResetTools(true, true);
}

function ResetSearch()
{
	RESPOKANEMAPOBJ.ResetSearch();
}

function ChangeMapType(sList)
{
	RESPOKANEMAPOBJ.SetMapType(sList.value);
}

function RemoveMapBox()
{
	RESPOKANEMAPOBJ.ResetAllToolsNoReCenter();
}

//disable select start in all for IE6 mostly
document.onselectstart = glDocSelStart;

function glDocSelStart(e)
{
	if (!e) 
		e = window.event;
	//see if we are text box
	if( e != null && e.srcElement != null && e.srcElement.type != null)
		return true;
	return false;
}
//end google map common

/*  RESPOKANEMapParams class
	by: randy bacon
	10/04/06
	Container for map params
*/

//RESPOKANEMapParams contants
var MLZOOMLEVEL_ELEM = "mLZoomLevel";
var MLNECORNER_ELEM = "mLNECorner";
var MLSWCORNDER_ELEM = "mLSWCorner";
var MLPOLYBOUNDS_ELEM = "mLPolyBounds";

function RESPOKANEMapParams()
{
	/* inline constructor */
	this.MLZoomLevel = document.getElementById(MLZOOMLEVEL_ELEM);
	this.MLNECorner = document.getElementById(MLNECORNER_ELEM);
	this.MLSWCorner = document.getElementById(MLSWCORNDER_ELEM);
	this.MLPolyBounds = document.getElementById(MLPOLYBOUNDS_ELEM);
}

//RESPOKANEMapParams :: Corners :: return the corners of our map in the right format (NE, SW)
RESPOKANEMapParams.prototype.Corners = function()
{
	return this.MLNECorner.value + "," + this.MLSWCorner.value;
}

//RESPOKANEMapParams :: toString :: overload to string to return useful information
RESPOKANEMapParams.prototype.toString = function()
{
	var rtrStr = "";
	rtrStr = "NE Corner: ";
	rtrStr += this.MLNECorner.value;
	rtrStr += "\nSW Corner: ";
	rtrStr += this.MLSWCorner.value;
	rtrStr += "\nZoom Level: ";
	rtrStr += this.MLZoomLevel.value;
	rtrStr += "\nPoly Bounds: ";
	rtrStr += this.MLPolyBounds.value;
	return rtrStr;
}
//end --------- RESPOKANEMapParams

/*  RESPOKANEZoomBox class
	by: randy bacon
	10/04/06
	Zoom box tool and functions
*/

//RESPOKANEZoomBox constants
var RESPOKANEZOOMBOX_ELEM = "respokaneZoomBox";

function RESPOKANEZoomBox()
{
	//private members
	this._InZoom = false;
	this._ZBoxStart;
	this._ZBoxEnd;
	this._ZStartBoxP;	//original pixel location
	this._IsComplete = false;
	this._Width = 0;
	this._Height = 0;
	this._BorderWidth = 4;
	this._InCenterAndZoom = false;
	
	//initialize
	this.Init();
	
	//properies
	this.MClickEnabled = false;
}

//RESPOKANEZoomBox :: Init :: Initialize tool
RESPOKANEZoomBox.prototype.Init = function()
{
	this.ZoomBox = document.getElementById(RESPOKANEZOOMBOX_ELEM);
	//always hide the box on start
	this.ZoomBox.style.display = "none";
}

//RESPOKANEZoomBox :: Reset:: method to reset this tool
RESPOKANEZoomBox.prototype.Reset = function()
{
	this.ZoomBox.style.display="none";
	this._InZoom = false;
	this.ZoomBox.style.cursor = "default";
	this._ZBoxStart = null;
	this._ZStartBoxP = null;
	this._ZBoxEnd = null;
	this._Width = 0;
	this._Height = 0;
	this._InCenterAndZoom = false;
}

//RESPOKANEZoomBox :: IsInCenterAndZoom:: returns InCenterAndZoom state
RESPOKANEZoomBox.prototype.IsInCenterAndZoom = function()
{
	return this._InCenterAndZoom;
}

//RESPOKANEZoomBox :: IsInSearch:: returns search state
RESPOKANEZoomBox.prototype.IsInSearch = function()
{
	return this._InZoom;
}

//RESPOKANEZoomBox :: IsBoxComplete:: returns true if we have a box on the map
RESPOKANEZoomBox.prototype.IsBoxComplete = function()
{
	return this._IsComplete;
}

//RESPOKANEZoomBox :: ResetComplete :: reset the complete status to state
RESPOKANEZoomBox.prototype.ResetComplete = function(state)
{
	return this._IsComplete = state;
}

//RESPOKANEZoomBox :: ClickSearchState :: enable/disable the click zoom function
RESPOKANEZoomBox.prototype.ClickSearchState = function()
{
	if(RESPOKANECURRTOOL == RESPOKANETOOLZOOMBOX)
	{
		this.MClickEnabled = true;
		RESPOKANEMAPOBJ.RESPOKANEMapOverlay.style.display = "inline";
		RESPOKANEMAPOBJ.RESPOKANEMapOverlay.style.cursor = "crosshair";
		document.getElementById(GOOGMAP_ELEM).style.cursor = "crosshair";
		RESPOKANEMAPOBJ.DisableG();
	}
	else
	{
		this.MClickEnabled = false;
		RESPOKANEMAPOBJ.RESPOKANEMapOverlay.style.display = "none";
		RESPOKANEMAPOBJ.RESPOKANEMapOverlay.style.cursor = "default";
		document.getElementById(GOOGMAP_ELEM).style.cursor = "default";
	}
}

//RESPOKANEZoomBox :: StartDraw :: starts the box draw if parameters are correct
RESPOKANEZoomBox.prototype.StartDraw = function()
{
	if( !this._InZoom && RESPOKANEMAPOBJ.PointerInMapBounds() )
	{
		this._IsComplete = false;
		//if all good start the draw 
		this._InZoom = true;
		RESPOKANEMAPOBJ.DisableG();
		this._ZBoxStart = RESPOKANEMAPOBJ.PixelToLatLng( new GPoint(MOUSELOCATION_X - RESPOKANEMAPOBJ.RESPOKANEMPixelOffset.x, MOUSELOCATION_Y - RESPOKANEMAPOBJ.RESPOKANEMPixelOffset.y) );
		//get our original location
		this._ZStartBoxP = new GPoint(MOUSELOCATION_X, MOUSELOCATION_Y);
		//set zoom box position
		this.ZoomBox.style.left = (MOUSELOCATION_X -  RESPOKANEMAPOBJ.RESPOKANEMPixelOffset.x) + "px";
		this.ZoomBox.style.top = (MOUSELOCATION_Y  -  RESPOKANEMAPOBJ.RESPOKANEMPixelOffset.y) + "px";
		this.ZoomBox.style.width = 0;
		this.ZoomBox.style.height = 0;
		//show the zoom box
		this.ZoomBox.style.display = "inline";
		//set cursor to crosshair
		this.ZoomBox.style.cursor = "crosshair";
		document.getElementById(GOOGMAP_ELEM).style.cursor = "crosshair";
		
		if( typeof(this._ZBoxStart) != 'undefined')
			RESPOKANEMAPOBJ.RemoveBorderBox();
	}
}
	
//RESPOKANEZoomBox :: EndDraw :: ends the box draw
RESPOKANEZoomBox.prototype.EndDraw = function()
{
	if( this._ZBoxStart == null || typeof(this._ZBoxStart) == 'undefined')
		return;
		
	if( this._InZoom )
	{
		if( RESPOKANEMAPOBJ.PointerInMapBounds() )
		{
			//end the box and draw
			this._InZoom = false;
			//get the end of the box
			this._ZBoxEnd = RESPOKANEMAPOBJ.PixelToLatLng( new GPoint(MOUSELOCATION_X - RESPOKANEMAPOBJ.RESPOKANEMPixelOffset.x, MOUSELOCATION_Y - RESPOKANEMAPOBJ.RESPOKANEMPixelOffset.y) );
			
			//see if our points got inversed
			if( this._ZBoxStart.y < this._ZBoxEnd.y )
			{
				var tempY = this._ZBoxStart.y;
				this._ZBoxStart.y = this._ZBoxEnd.y;
				this._ZBoxEnd.y = tempY;
			}
			
			if( this._ZBoxStart.x > this._ZBoxEnd.x )
			{
				var tempX = this._ZBoxStart.x;
				this._ZBoxStart.x = this._ZBoxEnd.x;
				this._ZBoxEnd.x = tempX;
			}
			
			//check our box size first
			if( this._Width > 5 ||  this._Height > 5 )
			{
				//tell we are done
				this._IsComplete = true;
				
				//set the zoom map bounds to find the center - put this in the zoom box class
				var neCrn = new GLatLng(this._ZBoxStart.y, this._ZBoxEnd.x);
				var swCrn = new GLatLng(this._ZBoxEnd.y, this._ZBoxStart.x);
				var rsBounds = new GLatLngBounds(swCrn, neCrn);
				
				document.getElementById('lat1').value = this._ZBoxStart.y;
				document.getElementById('long1').value = this._ZBoxEnd.x;
				document.getElementById('lat2').value = this._ZBoxEnd.y;
				document.getElementById('long2').value = this._ZBoxStart.x;
				
				//update our poly points
				var tempPoints = new Array();
				tempPoints[0] = neCrn;
				tempPoints[1] = swCrn;
				RESPOKANEMAPOBJ.PlyPoints = tempPoints;
				RESPOKANEMAPOBJ.LPolyBoundsChanged(tempPoints);			
								
				//redraw map - but tell zoom event we are in zoom and center
				this._InCenterAndZoom = true;
				RESPOKANEMAPOBJ.CenterMap(rsBounds);
				this._InCenterAndZoom = false;
							
				//draw box on map
				RESPOKANEMAPOBJ.DrawPolyBox(true, false);
			}
		}
		//regardless reset tools
		RESPOKANEMAPOBJ.ResetTools();
	}
}

//RESPOKANEZoomBox :: RESPOKANEZBMove :: handles move in the zoom tool
RESPOKANEZoomBox.prototype.Move = function()
{
	if (!this._InZoom)
		return;			
	
	if( this._ZBoxStart == null || typeof(this._ZBoxStart) == 'undefined')
		return;
		
	if(RESPOKANEMAPOBJ.PointerInMapBounds())
	{
		//move our box
		var w = parseFloat(MOUSELOCATION_X) - parseFloat(this._ZStartBoxP.x);
		var h = parseFloat(MOUSELOCATION_Y) - parseFloat(this._ZStartBoxP.y);
		if (w < 0) 
		{
			w = Math.abs(w);
			this.ZoomBox.style.left = (MOUSELOCATION_X - RESPOKANEMAPOBJ.RESPOKANEMPixelOffset.x) + "px";
		}  
		this._Width = w;
		if( (this._Width - this._BorderWidth) > 0 )
			this.ZoomBox.style.width = (this._Width - this._BorderWidth) + "px";
		//then set height
		if (h < 0)
		{
			h = Math.abs(h);
			this.ZoomBox.style.top = (MOUSELOCATION_Y - RESPOKANEMAPOBJ.RESPOKANEMPixelOffset.y) + "px";
		}  
		this._Height = h;
		if( (this._Height - this._BorderWidth) > 0 )
			this.ZoomBox.style.height = (this._Height - this._BorderWidth) + "px";
			
		document.getElementById("debug").value = this.ZoomBox.style.left + this.ZoomBox.style.top + this.ZoomBox.style.width + this.ZoomBox.style.height;
	}
	else //not in bounds reset the tool
	{
		RESPOKANEMAPOBJ.PlyPoints = null;
		RESPOKANEMAPOBJ.LPolyBoundsChanged(RESPOKANEMAPOBJ.PlyPoints);
		RESPOKANEMAPOBJ.ResetTools();
	}
}
//end --------- RESPOKANEZoomBox

